from datetime import datetime
import re
import random
from info.models import User
from info.response_code import RET
from . import passregister_bp
from flask import request, abort, current_app, make_response, jsonify, session
from info.utility.captcha.captcha import captcha
from info import redis_store, db
from info.constants import IMAGE_CODE_REDIS_EXPIRES, SMS_CODE_REDIS_EXPIRES
from info.lib.yuntongxun.sms import CCP


@passregister_bp.route('/image_code')
def passregister():
    code_id = request.args.get('code_id')
    if code_id:
        try:
            image_name, image_val, image_data = captcha.generate_captcha()
            print(image_val)
            redis_store.setex('CODEID_%s' % code_id, IMAGE_CODE_REDIS_EXPIRES, image_val)
        except Exception as e:
            current_app.logger.error(e)
    else:
        current_app.logger.error('参数不足')
        abort(404)
    response = make_response(image_data)
    response.headers['Content-Type'] = 'image/JPEG'
    return response


@passregister_bp.route('/smscode', methods=['POST'])
def smscode():
    """
    1.获取参数
        1.1 mobile: 手机号码， image_code:用户填写的图片验证码，image_code_id:UUID编号
    2.参数校验
        2.1 非空判断
        2.2 手机号码格式正则校验
    3.逻辑处理
        3.1 根据image_code_id编号去redis数据库获取真实的图片验证码值real_image_code
            3.1.1 real_image_code没有值：图片验证码过期了
            3.1.2 real_image_code有值： 将图片验证码从redis中删除（防止多次使用同一个验证码来进行多次验证码）
        3.2 对比用户添加的图片验证码值和真实的图片验证码值是否一致
            3.2.1 不相等：提示图片验证码填写错误，再次生成一张新的图片验证码即可
            3.2.2 相等：发送短信验证码

        TODO: 判断用户填写的手机号码是否已经注册（提高用户体验）

        3.3 发送短信验证码具体流程
            3.3.1 生成6位的随机短信验证码值
            3.3.2 调用CCP类中方法发送短信验证码
            3.3.3 发送短信验证码失败：提示前端重新发送
            3.3.4 将6位的短信验证码值使用redis数据库保存起来，设置有效时长（方便注册接口获取真实的短信验证值）
    4.返回值
        4.1 发送短信验证码成功
    """
    data = request.json
    phone = data.get('phone')
    image_val = data.get('image_val')
    image_code = data.get('image_code')
    if not all([phone, image_val, image_code]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")
    if not re.match('1[3456789]\d{9}', phone):
        return jsonify(errno=RET.PARAMERR, errmsg="手机格式错误")
    try:
        real_image_val = redis_store.get('CODEID_%s' % image_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="获取真实验证码错误")
    if not real_image_val:
        return jsonify(errno=RET.NODATA, errmsg="验证码已过期")
    else:
        try:
            redis_store.delete('CODEID_%s' % image_code)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="删除真实验证码错误")
    if image_val.lower() != real_image_val.lower():
        print('验证码填写错误')
        return jsonify(errno=RET.DATAERR, errmsg='验证码填写错误')
    try:
        user = User.query.filter(User.mobile == phone).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户手机号错误")
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg='用户已存在')
    else:
        note_code = '%06d' % random.randint(0, 999999)
        print(note_code)
        # 暂停短信功能
        # result = CCP().send_template_sms(phone, {note_code, SMS_CODE_REDIS_EXPIRES/60}, 1)
        # if result == -1:
        #     return jsonify(errno=RET.THIRDERR, errmsg='第三方系统错误')
        # if result == 0:
        #     redis_store.setex(phone, SMS_CODE_REDIS_EXPIRES, note_code)
        #     return jsonify(errno=RET.OK, errmsg='短信发送成功')
        redis_store.setex(phone, SMS_CODE_REDIS_EXPIRES, note_code)
        return jsonify(errno=RET.OK, errmsg='短信发送成功'+note_code)


@passregister_bp.route('/register', methods=['POST'])
def redister():
    data = request.json
    phone = data.get('phone')
    sms_val = data.get('sms_val')
    password = data.get('password')
    if not all([phone, sms_val, password]):
        return jsonify(errno=RET.DATAERR, errmsg='有填写项为空')
    try:
        real_sms_val = redis_store.get(phone)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="获取真实验证码有误")
    if not real_sms_val:
        return jsonify(errno=RET.NODATA, errmsg="没有验证码数据或已过期")
    else:
        try:
            redis_store.delete(phone)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg="删除验证码数据失败")
    if real_sms_val != sms_val:
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码错误")
    user = User()
    user.mobile = phone
    user.nick_name = phone
    user.last_login = datetime.now()
    user.password = password
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="用户添加到数据库失败")
    session['user_id'] = user.id
    session['mobile'] = user.mobile
    session['nick_name'] = user.nick_name
    return jsonify(errno=RET.OK, errmsg="注册成功")


@passregister_bp.route('/pass', methods=['POST'])
def enter():
    data = request.json
    mobile = data.get('mobile')
    password = data.get('password')
    if not all([mobile, password]):
        return jsonify(errno=RET.NODATA, errmsg='数据不能位空')
    if not re.match('1[13456789]\d{9}', mobile):
        return jsonify(errno=RET.DATAERR, errmsg='号码格式错误')
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    if not user:
        return jsonify(errno=RET.NODATA, errmsg='该用户不存在')
    if not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR, errmsg='密码错误')
    else:
        session['user_id'] = user.id
        session['nick_name'] = user.nick_name
        session['mobile'] = user.mobile
        session['is_admin'] = user.is_admin
        user.last_login = datetime.now()
        try:
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=RET.DBERR, errmsg="数据提交错误")
        return jsonify(errno=RET.OK, errmsg='登陆成功')


@passregister_bp.route('/login_out', methods=['POST'])
def login_out():
    session.pop('user_id')
    session.pop('mobile')
    session.pop('nick_name')
    session.pop('is_admin', '')
    return jsonify(errno=RET.OK, errmsg='退出登陆')

